import moment from 'moment';

// 向上取整十，整百，整千，整万
export const ceilNumber = (number) => {
    let bite = 0;
    if (number < 10) {
        return 10;
    }
    while (number >= 10) {
        number /= 10;
        bite += 1;
    }
    return Math.ceil(number) * Math.pow(10, bite);
};

// 向下取整十，整百，整千，整万
export const floorNumber = (number) => {
    let bite = 0;
    if (number < 10) {
        return 10;
    }
    while (number >= 10) {
        number /= 10;
        bite += 1;
    }
    return Math.floor(number) * Math.pow(10, bite);
};

//文件大小转化
export const fileSizeChange = (limit) => {
    let size = "";
    if (limit < 0.1 * 1024) {    //如果小于0.1KB转化成B
        size = limit.toFixed(2) + "B";
    } else if (limit < 0.1 * 1024 * 1024) {   //如果小于0.1MB转化成KB
        size = (limit / 1024).toFixed(2) + "KB";
    } else if (limit < 0.1 * 1024 * 1024 * 1024) {    //如果小于0.1GB转化成MB
        size = (limit / (1024 * 1024)).toFixed(2) + "MB";
    } else {
        size = (limit / (1024 * 1024 * 1024)).toFixed(2) + "GB";
    }
    let sizestr = size + "";
    let len = sizestr.indexOf("\.");
    let dec = sizestr.substr(len + 1, 2);
    if (dec === "00") {   //当小数点后为00时 去掉小数部分
        return sizestr.substring(0, len) + sizestr.substr(len + 3, 2);
    }
    return sizestr;
};

//返回数字的位数
export const NumberChange = (index, n) => {
    return (Array(n).join(0) + index).slice(-n);
};

//千分位转化
export const thousandChange = (num) => {
    return (num || 0).toString().replace(/(\d)(?=(?:\d{3})+$)/g, '$1,');
};

//时间转化
export const translateTime = (time) => {
    return moment(time).format("YYYY-MM-DD");
};

//时间转化
export const translateTime2 = (time) => {
    if (time) {
        return moment(time).format('YYYY/MM/DD HH:mm:ss')
    } else {
        return moment().format("YYYY/MM/DD HH:mm:ss");
    }
};

//时间转化
export const translateTime3 = (time) => {
    return moment(time).format('YYYY年MM月DD日 HH:mm:ss')
};

//时间转化
export const translateTime4 = (time) => {
    return moment(time || moment()).format('MM-DD HH:mm:ss')
};

//时间转化
export const translateTime5 = (time) => {
    return moment.unix(time).format('YYYY-MM-DD HH:mm:ss')
};

//时间转化
export const translateTime7 = (time) => {
    return moment.unix(time).format('MM月DD日')
};

//时间转化
export const translateTime8 = (time) => {
    let times = (moment().unix(time));
    return moment.unix(times).format('YYYY年MM月DD日')
};


//时间转化
export const translateTime9 = (time) => {
    return moment(time).format('YYYY-MM-DD')
};


//去除左右的空格
export const trimSpace = (str) => {
    return str.replace(/(^\s*)|(\s*$)/g, "");
};

//星期转换
export const weekChange = (date) => {
    let dateMap = {
        1: "周一",
        2: "周二",
        3: "周三",
        4: "周四",
        5: "周五",
        6: "周六",
        7: "周日",
    };
    let weekInfo = JSON.parse(date);
    let weekArr = [];
    weekInfo.forEach(item => {
        weekArr.push(dateMap[item]);
    });
    return weekArr.toString();
};

//日期转换
export const dateChange = (date) => {
    let dateInfo = JSON.parse(date);
    let dateArr = [];
    dateInfo.forEach(item => {
        dateArr.push((item));
    });
    return dateArr.toString();
};

//日期转换
export const dateChange2 = (date) => {
    let dateInfo = JSON.parse(date);
    let dateArr = [];
    dateInfo.forEach(item => {
        dateArr.push(`${(item.beginDate)}-${(item.endDate)}`);
    });
    return dateArr.toString();
};

// 手机号验证
export const validateMobile = (num) => {
    let reg = /^((1[3,8][0-9])|(14[5,6,7,9])|(15[1,2,3,5,6,7,8,9,0])|(16[2,5,6,7])|(17[1,2,3,4,5,6,7,8])|(19[1,3,5,6,7,8,9]))\d{8}$/;
    return reg.test(num);
};

// 并发请求 允许最大容量
// export const concurRequest = (urls, manNum, requestInfo, item) => {
//     return new Promise((resolve) => {
//         if ((urls.length) === 0) {
//             resolve(Array())
//         } else {
//             const result = Array();
//             let index = 0;  //下一个请求的下标
//             let count = 0; //当前请求的完成数量
//             async function request() {
//                 if (urls.length === index) {
//                     return false
//                 }
//                 const i = index; //保留当前请求的下标
//                 const url = urls[index]; //取到当前的请求的url
//                 index++;
//                 try {
//                     result[i] = await requestInfo(url);
//                 } catch (err) {
//                     result[i] = err
//                 } finally {
//                     count++;
//                     if (count === (urls.length)) {
//                         resolve(result)
//                     } else {
//                         // 已经发送的请求完成 需要再次发送一个请求
//                         await request();
//                     }
//                 }
//             }
//
//             //数组的长度和最大并发数的最小值
//             const times = Math.min(manNum, urls.length);
//             for (let i = 0; i < times; i++) {
//                 request();
//             }
//         }
//     });
// };

// 并发请求 允许最大容量
export const concurrencyRequest = (urls, maxNum, requestInfo) => {
    // 因为测试代码调用concurrencyRequest后需要返回一个Promise
    return new Promise((resolve) => {
        // urls的长度为0时，results就没有值，此时应该返回空数组
        if (urls.length === 0) {
            resolve([]);
            return;
        }
        const results = [];
        let index = 0; // 下一个请求的下标
        let count = 0; // 当前请求完成的数量
        // 发送请求
        async function request() {
            if (index === urls.length) return;
            const i = index; // 保存序号，使result和urls相对应
            const row = urls[index];
            index++;
            try {// 请求成功
                // resp 加入到results
                results[i] = await requestInfo({fileName:row.url});
            } catch (err) {
                // 请求失败
                // err 加入到results
                results[i] = err;
            } finally {// 请求失败或成功都补一个新的请求进来
                // 请求完成计数器
                count++;
                // 判断是否所有的请求都已完成
                if (count === urls.length) {
                    console.log('完成了');
                    resolve(results);
                }
                //
                await request();
            }
        }

        //  maxNum大于urls的长度时，应该取的是urls的长度，否则则是取maxNum
        const times = Math.min(maxNum, urls.length);
        // 开启第一次批量调用
        for(let i = 0; i < times; i++) {
            request().then(r => {});
        }
    })
}


// 判断url是否合法
export const isValidUrl = (url) => {
    let pattern = /^(?:\w+:)?\/\/([^\s\.]+\.\S{2}|localhost[\:?\d]*)\S*$/;
    return pattern.test(url);
};

// 转化成树形结构
export const toTree = (data, parentId, resp) => {
    data.forEach((item, index) => {
        Reflect.set(item, 'name', (item.deptName))
        Reflect.set(item, 'id', (item.deptId))
        if (item.parentId === parentId) {
            resp.push(item);
            //第二个参数为个数
            // data.splice(index, 1);
        }
    });
    resp.forEach((item) => {
        item.children = [];
        toTree(data, (item.deptId), (item.children));
        if ((((item.children).length) === 0)) {
            delete item.children;
        }
    });
    return resp
};

//获取get参数
export const getSearchParams = () => {
    let params = new URLSearchParams(window.location.search);
    return params.get('instance_id') || '';
};


// 获取周的中文名称
export const getWeek = (number) => {
    let type = parseInt(number);
    switch (type) {
        case 1:
            return '星期一';
        case 2:
            return '星期二';
        case 3:
            return '星期三';
        case 4:
            return '星期四';
        case 5:
            return '星期五';
        case 6:
            return '星期六';
        case 0:
            return '星期日';
    }
    return number
}

export const pxToVw = (size, baseSize = 1920) => {
    const baseSize1 = document.documentElement.clientWidth;
    let temp = (size / baseSize) * 100
    return `${temp}rem`
}

export const remToPx = (size, baseSize = 1920) => {
    const scale = document.documentElement.clientWidth / 1920;
    let temp = 19.2 * scale * size
    return `${temp}`
}


export const setHTMLFontSize = (baseSize = 19.2) => {
    const scale = document.documentElement.clientWidth / 1920;
    return `${(baseSize * Math.min(scale, 2))}px`
}

export const hasOverLayer = (element) => {
    let document = element.ownerDocument,
        rect = element.getBoundingClientRect(), // 获取目标的矩形信息
        x = rect.x,
        y = rect.y,
        width = rect.width,
        height = rect.height;

    x |= 0;
    y |= 0;
    width |= 0;
    height |= 0;
    // 四顶点取样
    let elements = [
        document.elementFromPoint(x + 1, y + 1),
        document.elementFromPoint(x + width - 1, y + 1),
        document.elementFromPoint(x + 1, y + height - 1),
        document.elementFromPoint(x + width - 1, y + height - 1)
    ];
    // 判断非本身及非子孙元素
    return elements.filter((el) => el !== null).some((el) => el !== element && !element.contains(el));
}


export const deepClone = (target, defaults) => {
    for (const [key, value] of Object.entries(defaults)) {
        if (typeof (value) !== null && typeof (value) === 'object') {
            deepClone(target[key], value);
        } else {
            if (!!target && Reflect.has(target, key)) {
                target[key] = target[key];
            } else {
                target[key] = defaults[key];
            }
        }
    }
    return target;
}

export const getQueryString = (name, url) => {
    const reg = new RegExp('[&, ?]' + name + '=([^\\&,\\#]*)', 'i');
    const value = reg.exec(url || location.href);
    return value ? value[1] : '';
}

export function getQueryParam(queryString = location.href) {
    const params = {};
    queryString = location.href.split('?')[1].split('&'); // 移除开头的'?'字符
    queryString.forEach((item)=>{
        params[item.split('=')[0]]= decodeURIComponent(item.split('=')[1])
    })
    return params;
}


// 节流函数:指定时间只执行第一次，当前时间结束
export const throttleFn = (fn, delay = 1000, err) => {
    let timer = null;
    let begin = new Date().getTime();
    return function () {
        const self = this;
        let args = Array.from(arguments);
        let current = new Date().getTime();
        clearInterval(timer);
        if ((current - begin) >= delay) {
            fn.call(self, args);
            begin = current;
        } else {
            timer = setTimeout(() => {
                fn.call(self, args);
            }, delay)
        }
    }
};

// 防抖函数:指定时间内只执行最后一次操作
export const debounceFn = (fn, delay = 1000, trigger) => {
    let res = null;
    let timer = null;
    let debounced = function () {
        const self = this;
        let args = arguments;
        //先清楚定时器在执行新的定时器
        if (timer) {
            clearTimeout(timer)
        }
        if (trigger) {
            let exec = !timer;
            timer = setTimeout(function () {
                timer = null;
            }, delay);
            if (exec) {
                res = fn.call(self, args)
            }
        } else {
            timer = setTimeout(function () {
                res = fn.call(self, args)
            }, delay);
        }
        return res;
    };
    debounced.remove = function () {
        clearTimeout(timer);
        timer = null;
    };
    return debounced;
};


export function  debounce(fun, delay = 500,immediate = true) {
    let  timer = null  //保存定时器
    return  function (args) {
        let  that = this
        let  _args = args
        if (timer) clearTimeout(timer);  //不管是否立即执行都需要首先清空定时器
        if (immediate) {
            if ( !timer) fun.apply(that, _args)  //如果定时器不存在,则说明延时已过,可以立即执行函数
            //不管上一个延时是否完成,都需要重置定时器
            timer = setTimeout(function(){
                timer = null; //到时间后,定时器自动设为null,不仅方便判断定时器状态还能避免内存泄露
            }, delay)
        }
        else {
            //如果是非立即执行版,则重新设定定时器,并将回调函数放入其中
            timer = setTimeout(function(){
                fun.call(that, _args)
            }, delay);
        }
    }
}


export const getImageExtension = (url) => {
    // 使用正则表达式匹配URL中的文件名部分，并获取最后一个点"."之后的部分
    const match = url.match(/.*\.(jpg|jpeg|png|gif|bmp|JPG|JPEG|PNG|GIF|BMP)$/);
    return match ? match[1] : null;
}

export const getImageName = (url) => {
// 获取图片名字
    return url.substring(url.lastIndexOf("/") + 1, url.lastIndexOf("."))
}
